/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package runebound.combate;

import runebound.modelo.heores.Heroe;
import runebound.modelo.monstruos.Monstruo;
import runebound.random.RBAzar;
import runebound.random.Tirada;

/**
 *
 * Calculadora de un combate. Es le modo más básico, carece de:
 *  - antes de combate
 *  - cualqueir tipo objetos
 *  - experienca
 * @author malopez
 */
public class RBCalculadoraCombate implements Runnable{

    private Heroe heroe;
    private Monstruo monstruo;
    private PlanCombate plan;
    private final Object lock = new Object();

    public RBCalculadoraCombate(Heroe heroe, Monstruo Monstruo) {
        this.heroe = heroe;
        this.monstruo = Monstruo;
    }
    
    
    
    @Override
    public void run() {
        registrar("Arranca combate: "+this.heroe.getNombre()+"vs"+this.monstruo.getTitulo());
        boolean seguirCombate = true;
        registrar("Se solicita plan de combate");
        while(seguirCombate){
            registrar("******");
            registrar(heroe.toString());
            registrar("VS");
            registrar(monstruo.toString());
            registrar("******");
            InterfazUsuarioCombate.getInstance().solicitarPlanCombate(this);
            if (!this.plan.isHuir()) {
                registrar("Comienza la fase de combate");
                registrar("Distancia");
                subFaseCombate(this.heroe.getValorCombateDistancia(), this.heroe.getFuerzaMente(), this.monstruo.getValorMente(), this.monstruo.getFuerzaMente(), plan.isAtacarDistancia());
                registrar("Melee");
                subFaseCombate(this.heroe.getValorCombateFisico(), this.heroe.getFuerzaFisico(), this.monstruo.getValorFisico(), this.monstruo.getFuerzaFisico(), plan.isAtacarMeele());
                registrar("Magia");
                subFaseCombate(this.heroe.getValorCombateMagia(), this.heroe.getFuerzaMagia(), this.monstruo.getValorMagia(), this.monstruo.getFuerzaMagia(), plan.isAtacarMagia());
                seguirCombate=!this.chequearFinCombate();
            } else {
                //TODO Tirar para huir
                seguirCombate = this.chequearHuir();
                registrar("El heroe huyo!!!");
            }

            
        }
        if(!plan.isHuir()&& !this.monstruo.isVivo()){
            registrar(""+this.heroe.getNombre()+" A vencido!");
        }else if(!plan.isHuir()&& !this.heroe.isVivo()){
            registrar(""+this.heroe.getNombre()+" A caido inconsciente. Vuelve a Talamir!");
        }else{
            registrar(""+this.heroe.getNombre()+" A huido con éxito!");
        }
        
    }

    /**
     * Subfase del combate
     * @param valorHeroe
     * @param fuerzaHeroe
     * @param valorMonstruo
     * @param fuerzaMonstruo
     * @param atacar 
     */
    private void subFaseCombate(int valorHeroe, int fuerzaHeroe, int valorMonstruo, int fuerzaMonstruo,boolean atacar) {
        registrar("H["+valorHeroe+"]vsM["+valorMonstruo+"]");
        Tirada tirada = RBAzar.getInstance().tiradaCombate();
        registrar(tirada.toString());
        boolean superaTirada = valorMonstruo<tirada.getTotal()+valorHeroe;
        if(atacar){
            
            if(superaTirada){
                registrar("El heroe ATACA y GOLPEA haciendo "+fuerzaHeroe+" heridas");
                monstruo.hit(fuerzaHeroe);
            }else{
                registrar("El heroe ATACA y FALLA recibiendo"+fuerzaMonstruo+" heridas");
                heroe.hit(fuerzaMonstruo);
            }
        }else{
            if(superaTirada){
                registrar("El heroe DEFIENDE y salva el golpe");
            }else{
                registrar("El heroe DEFIENDE y FALLA recibiendo"+fuerzaMonstruo+" heridas");
                heroe.hit(fuerzaMonstruo);
            }
        }
    }

    private void registrar(String cadena) {
        RBRegistroInformacion.getInstance().registro(new LineaRegistroString(cadena));
    }

    public void setPlan(PlanCombate plan) {
        this.plan = plan;
        synchronized(this.lock){
            
            this.lock.notifyAll();
        }
    }

    private boolean chequearFinCombate() {
        
        return !heroe.isVivo()||!this.monstruo.isVivo();
    }

    /**
     * Prueba de huir
     * @return 
     */
    private boolean chequearHuir() {
        Tirada tirada = RBAzar.getInstance().tiradaCombate();
        registrar("HUIR:"+tirada.toString());
        return tirada.getTotal()>=this.monstruo.getValorMente();
    }
    
    
    
    
}
